import { Controller, Inject, Body, Post, Get, Query, SetMetadata, HttpCode, ParseIntPipe, BadRequestException, DefaultValuePipe, HttpStatus } from '@nestjs/common';
import { UserService } from './user.service';
import RegisterUserDto from './dto/RegisterUserDto';
import LoginDto from './dto/LoginDto';
import { LoginUserVo } from './vo/LoginUserVo';
import { EmailPipe } from 'src/common/pipe/email.pipe';
import { RequireLogin, RequirePermission, UserInfo } from 'src/common/decorator/permission.decorator';
import { UserDetailVo } from './vo/UserDetailVo';
import { copyProperties, generateParseIntPipe } from 'src/common/utils';
import { PasswordDto } from './dto/PasswordDto';
import { UpdateUserDto } from './dto/UpdateUserDto';
import { ApiBearerAuth, ApiBody, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { RefreshTokenVo } from './vo/RefreshTokenVo';
import { ResultData } from 'src/common/utils/result';
@ApiTags('用户管理模块')
@Controller('user')
export class UserController {
    @Inject()
    private readonly userService: UserService;

    @ApiQuery({
        name: 'address',
        type: String,
        description: '邮箱地址',
        required: true,
        example: 'xxx@xx.com'
    })
    @ApiResponse({
        status: HttpStatus.OK,
        description: '发送成功',
        type: String
    })
    @Get('register-captcha')
    async captcha(@Query(`address`, EmailPipe) address: string) {
        try {
            const res = await this.userService.captcha(address)
            return ResultData.ok(null, `发送成功`)
        } catch (err) {
            console.log(err);
            if (err.responseCode == 550) {
                return ResultData.fail(550, '错误的邮箱地址', null)
            }
            return ResultData.fail(550, '发送邮件失败', null)
        }
    }

    @ApiQuery({
        name: 'address',
        description: '邮箱地址',
        type: String
    })
    @ApiResponse({
        type: String,
        description: '发送成功'
    })
    @Get(`update-password/captcha`)
    async updatePasswordCaptcha(@Query(`address`, EmailPipe) address: string) {
        await this.userService.updatePasswordCaptcha(address)
        return ResultData.ok(null, `发送成功`)
    }

    @Get(`update/captcha`)
    async updateCaptcha(@Query(`address`, EmailPipe) address: string) {
        await this.userService.updateCaptcha(address)
        return ResultData.ok(null, `发送成功`)
    }

    @ApiBody({ type: RegisterUserDto })
    @ApiResponse({
        status: HttpStatus.BAD_REQUEST,
        description: '验证码已失效/验证码不正确/用户已存在',
        type: String
    })
    @ApiResponse({
        status: HttpStatus.OK,
        description: '注册成功/失败',
        type: String
    })
    @Post('register')
    async register(@Body() registerUserDto: RegisterUserDto) {
        const { code, msg } = await this.userService.register(registerUserDto);
        if (code === 200) {
            return ResultData.ok(null, msg)
        } else {
            return ResultData.fail(code, msg, null)
        }
    }

    @ApiBody({
        type: LoginDto
    })
    @ApiResponse({
        status: HttpStatus.BAD_REQUEST,
        description: '用户不存在/密码错误',
        type: String
    })
    @ApiResponse({
        status: HttpStatus.OK,
        description: '用户信息和 token',
        type: LoginUserVo
    })

    @Post('login')
    @HttpCode(200)
    async userLogin(@Body() loginDto: LoginDto) {
        let user = await this.userService.login(loginDto)
        return ResultData.ok(user, '用户登录成功')
    }

    @Post('admin/login')
    async adminLogin(@Body() loginDto: LoginDto) {
        let adminUser = await this.userService.login(loginDto, true)
        return ResultData.ok(adminUser, '用户登录成功')
    }

    @ApiQuery({
        name: 'refreshToken',
        type: String,
        description: '刷新 token',
        required: true,
        example: 'xxxxxxxxyyyyyyyyzzzzz'
    })
    @ApiResponse({
        status: HttpStatus.UNAUTHORIZED,
        description: 'token 已失效，请重新登录'
    })
    @ApiResponse({
        status: HttpStatus.OK,
        description: '刷新成功',
        type: RefreshTokenVo
    })

    @Get('refresh')
    async refresh(@Query('refreshToken') refreshToken: string) {
        const refreshTokenVo = await this.userService.refresh(refreshToken, false)
        return ResultData.ok<RefreshTokenVo>(refreshTokenVo, '刷新成功')
    }
    @Get('admin/refresh')
    async adminRefresh(@Query('refreshToken') refreshToken: string) {
        const refreshTokenVo = await this.userService.refresh(refreshToken, true)
        return ResultData.ok<RefreshTokenVo>(refreshTokenVo, '刷新成功')
    }

    @ApiBearerAuth()
    @ApiResponse({
        status: HttpStatus.OK,
        description: 'success',
        type: UserDetailVo
    })
    @Get('info')
    @RequireLogin()
    async info(@UserInfo('userId') userId: number) {
        const userInfo = await this.userService.findUserDetailById(userId)
        const userDetailVo = new UserDetailVo()
        copyProperties(userInfo, userDetailVo)
        return ResultData.ok<UserDetailVo>(userDetailVo);
    }

    @ApiBody({
        type: PasswordDto
    })
    @ApiResponse({
        type: String,
        description: '验证码已失效/不正确'
    })

    @Post(['update_password', 'admin/update_password'])
    async updatePassword(@Body() passwordDto: PasswordDto) {
        const { code, msg } = await this.userService.updatePassword(passwordDto)
        if (code === 200) {
            return ResultData.ok(null, msg)
        } else {
            return ResultData.fail(code, msg, null)
        }
    }


    @ApiBearerAuth()
    @ApiBody({
        type: UpdateUserDto
    })
    @ApiResponse({
        status: HttpStatus.BAD_REQUEST,
        description: '验证码已失效/不正确'
    })
    @ApiResponse({
        status: HttpStatus.OK,
        description: '更新成功',
        type: String
    })
    @Post([`update`, `admin/update`])
    @RequireLogin()
    async update(@UserInfo('userId') userId: number, @Body() updateUserDto: UpdateUserDto) {
        const { code, msg } = await this.userService.update(userId, updateUserDto)
        if (code === 200) {
            return ResultData.ok(null, msg)
        } else {
            return ResultData.fail(code, msg, null)
        }
    }

    @ApiBearerAuth()
    @ApiQuery({
        name: 'id',
        description: 'userId',
        type: Number
    })
    @ApiResponse({
        type: String,
        description: 'success'
    })
    @RequireLogin()

    @Get('freeze')
    async freeze(@Query('id') userId: number) {
        await this.userService.freeze(userId)
        return ResultData.ok(null, '冻结成功')
    }

    @ApiBearerAuth()
    @ApiQuery({
        name: 'pageNo',
        description: '第几页',
        type: Number
    })
    @ApiQuery({
        name: 'pageSize',
        description: '每页多少条',
        type: Number
    })
    @ApiQuery({
        name: 'username',
        description: '用户名',
        type: Number
    })
    @ApiQuery({
        name: 'nickName',
        description: '昵称',
        type: Number
    })
    @ApiQuery({
        name: 'email',
        description: '邮箱地址',
        type: Number
    })
    @ApiResponse({
        type: String,
        description: '用户列表'
    })
    @RequireLogin()
    @Get('list')
    async list(
        @Query('pageNo', new DefaultValuePipe(1), generateParseIntPipe('pageNo')) pageNo: number,
        @Query('pageSize', new DefaultValuePipe(2), generateParseIntPipe('pageSize')) pageSize: number,
        @Query('username') username: string,
        @Query('nickName') nickName: string,
        @Query('email') email: string
    ) {
        // return this.userService.findUserByPage(pageNo, pageSize)
        const userListVo = this.userService.findUsers(username, nickName, email, pageNo, pageSize)
        return ResultData.ok(userListVo)
    }

    @Get('/aaa')
    @RequireLogin()
    @RequirePermission('ddd')
    aaa(@UserInfo('username') username: string) {
        console.log(username);
        return 'aaa'
    }

    @Get("init-data")
    async initData() {
        await this.userService.initData();
        return 'done';
    }

}
